package com.coolrui.domain.statemachine;

import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.StateMachineFactory;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.coolrui.domain.statemachine.dto.OrderContext;
import com.coolrui.domain.statemachine.enums.OrderEvent;
import com.coolrui.domain.statemachine.enums.OrderState;
import com.coolrui.domain.statemachine.handler.OrderCancelHandle;
import com.coolrui.domain.statemachine.handler.OrderPayHandle;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component
@AllArgsConstructor
public class OrderStateMachine {
    public static final String MACHINE_ID = "ORDER_STATE_MACHINE";
    @Autowired
    private final OrderPayHandle orderPayHandle;
    @Autowired
    private final OrderCancelHandle orderCancelHandle;

    @PostConstruct
    public StateMachine<OrderState, OrderEvent, OrderContext> createStateMachine() {
        // 创建状态机
        StateMachineBuilder<OrderState, OrderEvent, OrderContext> builder = StateMachineBuilderFactory.create();

        // 外部状态流转 从《初始待支付》到《待派单》， 需要触发《订单支付》操作
        builder.externalTransition()
                .from(OrderState.INIT)
                .to(OrderState.WAIT_ASSIGN)
                .on(OrderEvent.PAY)
                .when(orderPayHandle.checkCondition()).perform(orderPayHandle.doAction());

        // 外部状态流转-多个起始状态，从允许用户取消的状态到《已取消》，需要触发《取消订单》操作
        builder.externalTransitions()
                .fromAmong(
                        OrderState.INIT,
                        OrderState.WAIT_ASSIGN,
                        OrderState.WAIT_SERVICE
                )
                .to(OrderState.CANCELED)
                .on(OrderEvent.CANCEL)
                .when(orderCancelHandle.checkCondition()).perform(orderCancelHandle.doAction());
        return builder.build(MACHINE_ID);
    }

    public static StateMachine<OrderState, OrderEvent, OrderContext> getStateMachine() {
        return StateMachineFactory.get(MACHINE_ID);
    }

}

